package net.pimpas.util;

import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;

import net.pimpas.util.reflection.ReflectionUtils;

/**
 * 
 * @author pc
 *
 */
public abstract class EqualsHelper {
	
	public static <T extends Object> boolean equals(T obj1, Object obj2) {
		if(obj1 == null || obj2 == null) return false;
		BeanInfo bi = ReflectionUtils.instanceBeanInfo(obj1.getClass());
		PropertyDescriptor[] pds = bi.getPropertyDescriptors();
		Collection<String> properties = new ArrayList<String>();
		for(PropertyDescriptor pd: pds)
			properties.add(pd.getName());
		String[] arrayProperties = new String[properties.size()];
		properties.toArray(arrayProperties);
		
		return equals(obj1, obj2, arrayProperties);
	}
	
	public static <T extends Object> boolean equals(T obj1, Object obj2, String... properties) {
		if(obj2 == null || obj1 == null) return false;
		if(!ReflectionUtils.isSubclass(obj2.getClass(), obj1.getClass())) return false;
		Object pObj1 = null;
		Object pObj2 = null;
		boolean equals = true;
		for(String property: properties) {
			pObj1 = null;
			pObj2 = null;
			try {
				pObj1 = ReflectionUtils.getPropertyValue(
							ReflectionUtils.getPropertyDescriptor(obj1.getClass(), property),
						obj1);
				pObj2 = ReflectionUtils.getPropertyValue(
						ReflectionUtils.getPropertyDescriptor(obj1.getClass(), property),
					obj2);
			} catch(Exception e) {
				return false;
			}
			
			if(pObj1 == null && pObj2 == null) continue;
			if( (pObj1 == null && pObj2 != null ) || (pObj1 != null && pObj2 == null)) equals = false;
			else
				if(!pObj1.equals(pObj2)) equals = false;
			if(!equals) return false;
		}
		
		return true;
	}
}